package com.ky.manage.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ContextThemeWrapper;
import androidx.customview.widget.ViewDragHelper;
import androidx.drawerlayout.widget.DrawerLayout;

import com.github.anrwatchdog.ANRError;
import com.ky.manage.BaseApplication;
import com.ky.manage.activity.SplashActivity;
import com.ky.manage.permission.AndPermissionUtils;
import com.snail.permission.runtime.Permission;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 工具类
 *
 * @author zhaoyan
 * @date 2019-11-07
 */
public class Utils {
    private static final String TAG = Utils.class.getSimpleName();
    /**
     * 设备屏幕信息
     * 华为m5 :density=2.25, width=1837, height=1200
     * 联想：density=2.0, width=1920, height=1104 屏幕是960dp*552dp（UI之前以这个适配）
     * 以高度为维度，适配后的 density = 设备真实高(单位px)/552
     */
    private static DisplayMetrics sDisplayMetrics;

    /**
     * 解析HTML到文本
     *
     * @param filePath: html file path
     * @return string
     */
    public static String getStringFromHtmlFile(String filePath) {
        String result = "";
        if (TextUtils.isEmpty(filePath)) {
            return result;
        }
        Context context = BaseApplication.getContext();
        InputStream stream = null;
        BufferedReader reader = null;
        InputStreamReader streamReader = null;
        try {
            // Read html file into buffer
            stream = context.getAssets().open(filePath);
            streamReader = new InputStreamReader(stream, StandardCharsets.UTF_8);
            reader = new BufferedReader(streamReader);
            StringBuilder builder = new StringBuilder();
            String line = null;

            boolean readCurrentLine = true;
            // Read each line of the html file, and build a string.
            while ((line = reader.readLine()) != null) {
                // Don't read the Head tags when CSS styling is not supporeted.
                if (line.contains("<style")) {
                    readCurrentLine = false;
                } else if (line.contains("</style")) {
                    readCurrentLine = true;
                }
                if (readCurrentLine) {
                    builder.append(line).append("\n");
                }
            }
            result = builder.toString();
        } catch (FileNotFoundException ex) {
        } catch (Exception ex) {
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException ex) {
                }
            }
            if (null != streamReader) {
                try {
                    streamReader.close();
                } catch (IOException ex) {
                }
            }
            if (null != stream) {
                try {
                    stream.close();
                } catch (IOException ex) {
                }
            }
        }
        return result;
    }

    /**
     * Get activity from context object
     *
     * @param context context
     * @return object of Activity or null if it is not Activity
     */
    public static Activity scanForActivity(Context context) {
        if (context == null) return null;

        if (context instanceof Activity) {
            return (Activity) context;
        } else if (context instanceof ContextWrapper) {
            return scanForActivity(((ContextWrapper) context).getBaseContext());
        }

        return null;
    }

    /**
     * Get AppCompatActivity from context
     *
     * @param context context
     * @return AppCompatActivity if it's not null
     */
    public static AppCompatActivity getAppCompActivity(Context context) {
        if (context == null) return null;
        if (context instanceof AppCompatActivity) {
            return (AppCompatActivity) context;
        } else if (context instanceof ContextThemeWrapper) {
            return getAppCompActivity(((ContextThemeWrapper) context).getBaseContext());
        }
        return null;
    }

    /**
     * 重启应用
     */
    public static void restartApplication() {
        try {
            Context context = BaseApplication.getContext();
            Intent intent = new Intent(context, SplashActivity.class);
            PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, restartIntent);
        } catch (NullPointerException e) {
        } catch (Exception e) {
        }
        android.os.Process.killProcess(android.os.Process.myPid());
    }

    /**
     * wifi开启状态
     *
     * @return
     */
    public static boolean isWifiEnable() {
        boolean isWifiEnabled = false;
        Context context = BaseApplication.getContext();
        try {
            WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            isWifiEnabled = wifiManager.isWifiEnabled();
        } catch (Exception e) {
        }
        return isWifiEnabled;
    }

    /**
     * 获取屏幕信息
     *
     * @return
     */
    public static DisplayMetrics getDeviceDisplayInfo() {
        if (null == sDisplayMetrics) {
            Context context = BaseApplication.getContext();
            WindowManager wm = (WindowManager) context.getSystemService(
                    Context.WINDOW_SERVICE);
            sDisplayMetrics = new DisplayMetrics();
            wm.getDefaultDisplay().getMetrics(sDisplayMetrics);
//        metrics.heightPixels = 1920
//        metrics.widthPixels = 1080
//        metrics.densityDpi = 480   //dpi值
//        metrics.density = 3.0   //基准比例，dpi/160
//        metrics.xdpi = 422.03    //x方向准确的物理像素密度
//        metrics.ydpi = 424.069  //y方向准确的物理像素密度
//        metrics.scaledDensity = 3.0
        }
        return sDisplayMetrics;
    }

    /**
     * 安装app包方法
     *
     * @param apkfile
     */
    public static void installApp(final File apkfile) {
        Context context = BaseApplication.getContext();
        if (null == apkfile || !apkfile.exists()) {
            ToastUtils.showToast("app升级包不存在");
            return;
        }
        if (apkfile.length() > 1024 * 1024 * 20) {
            //下载apk的versionCode >= 当前运行apk的versionCode, 启动系统安装器安装apk
            if (PackageUtils.isDownloadApkCanInstall()) {
                AndPermissionUtils.getInstance().installApp(context, apkfile);
            } else {
                //这种场景是服务端放置的升级包低于已安装的版本号（versionCode）
                ToastUtils.showToast("当前已是最新版本");
            }
        } else {
            ToastUtils.showToast("app包下载错误，请稍后再试");
            return;
        }
    }

    /**
     * 启动服务
     *
     * @param serviceCls
     * @param bundle
     */
    public static void startService(Class<?> serviceCls, Bundle bundle) {
        Context context = BaseApplication.getContext();
        Intent intent = new Intent(context, serviceCls);
        if (null != bundle) {
            intent.putExtras(bundle);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        } else {
            context.startService(intent);
        }
    }

    /**
     * 终止服务
     *
     * @param serviceCls
     */
    public static void stopService(Class<?> serviceCls) {
        Context context = BaseApplication.getContext();
        Intent intent = new Intent(context, serviceCls);
        context.stopService(intent);
    }

    /**
     * 淡入淡出动画方法
     *
     * @param
     */
    public static void startAnimation(View view) {
        if (null == view || null != view.getAnimation()) {
            return;
        }
        // 创建透明度动画，第一个参数是开始的透明度，第二个参数是要转换到的透明度
        AlphaAnimation alphaAni = new AlphaAnimation(1f, 0);
        //设置动画执行的时间，单位是毫秒
        alphaAni.setDuration(500);
        // 设置动画重复次数
        // -1或者Animation.INFINITE表示无限重复，正数表示重复次数，0表示不重复只播放一次
        alphaAni.setRepeatCount(Animation.INFINITE);
        // 设置动画模式（Animation.REVERSE设置循环反转播放动画,Animation.RESTART每次都从头开始）
        alphaAni.setRepeatMode(Animation.REVERSE);
        // 启动动画
        view.startAnimation(alphaAni);
    }

    /**
     * 关闭动画
     *
     * @param view
     */
    public static void closeAnimation(View view) {
        if (null == view) {
            return;
        }
        view.clearAnimation();
    }

    /**
     * 队列插入数据
     *
     * @param dataQueue
     * @param insertBytes
     * @param queueFullClear 队列满了是否清空队列
     */
    public static boolean insertBlockingQueue(ArrayBlockingQueue<byte[]> dataQueue, byte[] insertBytes
            , boolean queueFullClear) {
        if (null == dataQueue || null == insertBytes) {
            return false;
        }
        boolean insertSuccess = dataQueue.offer(insertBytes);
        if (!insertSuccess && queueFullClear) {
            dataQueue.clear();
        }
        return insertSuccess;
    }

    /**
     * 清除队列中的数据
     *
     * @param dataQueue
     */
    public static void clearBlockingQueue(ArrayBlockingQueue<byte[]> dataQueue) {
        if (null == dataQueue) {
            return;
        }
        dataQueue.clear();
    }

    /**
     * 字节数组转16进制字符串
     *
     * @param data
     * @return
     */
    public static String byteArrToHex(byte[] data) {
        if (null == data || data.length == 0) {
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        try {
            for (int i = 0; i < data.length; i++) {
                int v = data[i] & 0xFF;
                String hv = Integer.toHexString(v);
                if (hv.length() < 2) {
                    stringBuilder.append(0);
                }
                stringBuilder.append(hv.toUpperCase());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuilder.toString();
    }

    /**
     * 字节数组转字符串
     *
     * @param bytes
     */
    public static void byteArrToString(byte[] bytes) {
        try {
            String strGBK = new String(bytes, "GBK");
        } catch (Exception e) {

        }
    }

    /**
     * 判断数据是否为空
     *
     * @param txt
     * @return
     */
    public static boolean isEmptyTxt(String txt) {
        return TextUtils.isEmpty(txt) || "null".equals(txt);
    }

    /**
     * 设置drawerLayout侧滑EdgeSize:左侧边栏
     *
     * @param activity
     * @param drawerLayout
     * @param displayWidthPercentage
     */
    public static void setDrawerLeftEdgeSize(Activity activity, DrawerLayout drawerLayout, float displayWidthPercentage) {
        if (activity == null || drawerLayout == null) {
            return;
        }
        try {
            // 找到 ViewDragHelper 并设置 Accessible 为true
            Field leftDraggerField = drawerLayout.getClass().getDeclaredField("mLeftDragger");
            if (null == leftDraggerField) {
                return;
            }
            leftDraggerField.setAccessible(true);
            ViewDragHelper leftDragger = (ViewDragHelper) leftDraggerField.get(drawerLayout);
            if (null == leftDragger) {
                return;
            }
            // 找到 edgeSizeField 并设置 Accessible 为true
            Field edgeSizeField = leftDragger.getClass().getDeclaredField("mEdgeSize");
            if (null == edgeSizeField) {
                return;
            }
            edgeSizeField.setAccessible(true);
            int edgeSize = edgeSizeField.getInt(leftDragger);
            // 设置新的边缘大小
            Point displaySize = new Point();
            activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
            int newEdgeSize = (int) (displaySize.x * displayWidthPercentage);
//            LogUtils.d("zhaoyan", "setDrawerLeftEdgeSize edgeSize = " + edgeSize);
            edgeSizeField.setInt(leftDragger, Math.max(edgeSize, newEdgeSize));
        } catch (NoSuchFieldException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        } catch (Exception e) {
        }
    }

    /**
     * kill process by package name
     *
     * @param packageName
     * @param context
     */
    public static void killProcessByPackageName(Context context, String packageName) {
        ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo appProcessInfo : appProcessList) {
            // 进程名，默认是包名或者由属性android：process=""指定
            String processName = appProcessInfo.processName;
            if (processName.equals(packageName)) {
                mActivityManager.killBackgroundProcesses(processName);
                android.os.Process.killProcess(appProcessInfo.pid);
                break;
            }
        }
    }


    public static void startAppFromPackageName(Context context, String packageName) {
        PackageManager packageManager = context.getPackageManager();
        Intent intent = packageManager.getLaunchIntentForPackage(packageName);
        context.startActivity(intent);
    }

    public static boolean isMainProcess(Context context) {
        try {
            Class<?> clazz = Class.forName("android.app.ActivityThread");
            Method currentActivityThreadMethod = clazz.getDeclaredMethod("currentActivityThread");
            currentActivityThreadMethod.setAccessible(true);
            Object tCurrentActivityThread = currentActivityThreadMethod.invoke(null);

            Method tGetProcessNameMethod = clazz.getDeclaredMethod("getProcessName");
            tGetProcessNameMethod.setAccessible(true);
            String tProcessName = (String) tGetProcessNameMethod.invoke(tCurrentActivityThread);
            return context.getPackageName().equalsIgnoreCase(tProcessName);
        } catch (Throwable e) {
            return true;
        }
    }

    /**
     * 判断是否为乱码
     * @param strName
     * @return
     */
    public static boolean isMessyCode(String strName) {
        if (TextUtils.isEmpty(strName)) {
            return false;
        }
        try {
            Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
            Matcher m = p.matcher(strName);
            String after = m.replaceAll("");
            String temp = after.replaceAll("\\p{P}", "");
            char[] ch = temp.trim().toCharArray();

            int length = (ch != null) ? ch.length : 0;
            for (int i = 0; i < length; i++) {
                char c = ch[i];
                if (!Character.isLetterOrDigit(c)) {
                    String str = "" + ch[i];
                    if (!str.matches("[\u4e00-\u9fa5]+")) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }


    /**
     * 收集anr日志
     *
     * @param ex
     */
    public static void collectANRError(ANRError ex) {
        Context context = BaseApplication.getContext();
        if (!AndPermissionUtils.getInstance().hasStoragePermission()) {
            return;
        }
        //用来存储设备信息和异常信息
        Map<String, String> infoMap = new HashMap<>();
        DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd_HH_mm_ss");
        //收集设备信息
        try {
            PackageManager pm = context.getPackageManager();
            PackageInfo pi = pm.getPackageInfo(context.getPackageName(),
                    PackageManager.GET_ACTIVITIES);
            if (pi != null) {
                String versionName = pi.versionName == null ? "null"
                        : pi.versionName;
                String versionCode = pi.versionCode + "";
                infoMap.put("versionName", versionName);
                infoMap.put("versionCode", versionCode);
            }
        } catch (PackageManager.NameNotFoundException e) {
        }

        Field[] fields = Build.class.getDeclaredFields();
        for (Field field : fields) {
            try {
                field.setAccessible(true);
                infoMap.put(field.getName(), field.get(null).toString());
            } catch (Exception e) {
            }
        }

        //异常日志存储
        StringBuffer sb = new StringBuffer();
        for (Map.Entry<String, String> entry : infoMap.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            sb.append(key + "=" + value + "\n");
        }

        Writer writer = new StringWriter();
        PrintWriter printWriter = new PrintWriter(writer);
        ex.printStackTrace(printWriter);
        Throwable cause = ex.getCause();
        while (cause != null) {
            cause.printStackTrace(printWriter);
            cause = cause.getCause();
        }
        printWriter.close();
        String result = writer.toString();
        sb.append(result);
        String crashInfo = sb.toString();
        try {
            long timestamp = System.currentTimeMillis();
            String time = dateFormatter.format(new Date());
            String fileName = "anr_zy_" + time + "_" + timestamp + ".txt";
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                // save in sdcard
                File sdCardFile = Environment.getExternalStorageDirectory();
                String sdCardPath = sdCardFile.getAbsolutePath() + "/zyAnr/";
                File dir = new File(sdCardPath);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                FileOutputStream fos = new FileOutputStream(sdCardPath
                        + fileName);
                fos.write(crashInfo.getBytes());
                fos.close();
            }
        } catch (Exception e) {
        }
    }


    public static boolean CheckMobilePhoneNum(String phoneNum) {
        String regex = "^(1[3-9]\\d{9}$)";
        if (phoneNum.length() == 11) {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phoneNum);
            if (m.matches()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 拨打电话（直接拨打电话）
     * @param context
     * @param phoneNum 电话号码
     */
    public static void callPhone(Context context, String phoneNum){
        if (TextUtils.isEmpty(phoneNum)) {
            return;
        }
        AndPermissionUtils.getInstance().requestPermission(context, new AndPermissionUtils.PermissionRequestListener() {
            @Override
            public void onGranted() {
                Intent intent = new Intent(Intent.ACTION_CALL);
                Uri data = Uri.parse("tel:" + phoneNum);
                intent.setData(data);
                context.startActivity(intent);
            }

            @Override
            public void onDenied(List<String> data) {
                ToastUtils.showRoundRectToast("未授权：拨打电话权限");
            }
        }, true, Permission.CALL_PHONE);
    }
}
